feat: add dynamicColor prop and DynamicTheme refactor#4925
Conversation
|
The mobile version of example app from this branch is ready! You can see it here. |
62ea8dc to
96603d4
Compare
|
Hey @adrcotfas, thank you for your pull request 🤗. The documentation from this branch can be viewed here. |
27f7121 to
a9ec233
Compare
96603d4 to
d51258f
Compare
| theme?: ThemeProp; | ||
| settings?: Settings; | ||
| reduceMotion?: ReduceMotionPreference; | ||
| dynamicColor?: boolean; |
There was a problem hiding this comment.
This shouldn't be a prop. We should export dynamic themes like any other theme, which makes it possible for the consumer to customize it, provide their own dynamic theme without using our helpers, and keep the API consistent, same as non-dynamic themes. I don't see a reason to make it work differently.
The merging can be done before exporting and theme can handle fallbacks for older version/other platforms etc. to reduce boilerplate. So the user just needs to import and pass it (and optionally customize it).
| const ac = (name: string) => | ||
| PlatformColor(`@android:color/${name}`) as unknown as string; |
There was a problem hiding this comment.
Not done in this PR but this is a problem. The theme should have colors as ColorValue, not string. There shouldn't be any type casting.
Motivation
Before this PR, using dynamic colors required every consumer to wire up the same boilerplate: import
DynamicLightTheme/DynamicDarkTheme, detect Android API 31+ themselves, write a useMemo to switch between them, and keep it in sync with dark mode. The library provided the building blocks but left the assembly to the app.This PR absorbs that complexity into
PaperProvidervia a singledynamicColorprop. PassdynamicColorand the provider handles palette selection, API level detection, dark/light switching, and graceful fallback on iOS/web -- with no app-side logic needed.Alongside that, the
DynamicTheme.android.tsximplementation is refactored from ~500 lines of repetitive pick() calls into a typed role-map table with Palette.* ref constants as ground truth. This fixes two latent bugs in the original: error roles and MCL-only surface roles were calling PlatformColor with hex strings on API 31-33 (invalid, silently transparent), andsurfaceVariantwas missing its API 31 accent resources entirely.Other changes in scope:
ThemeBaseinlined intoTheme(kept as a deprecated Pick<> alias), andisDynamicColorSupportedexported from the library root so consumers can conditionally show a dynamic theme toggle without re-implementing the platform check.Related issue
See https://www.notion.so/callstack/React-Native-Paper-Foundation-for-MD3-Expressive-34c5d027c0f880edba3df107cd35946f?source=copy_link
Merge order:
Test plan
yarn typescript-- no new type errorsyarn test-- all tests pass